package com.seaside.park.scheduled;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.seaside.common.bean.Result;
import com.seaside.park.component.ReadYZNo;
import com.seaside.parkCommon.bean.*;
import com.seaside.parkCommon.mapper.*;
import com.seaside.parkCommon.service.PushService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
@Slf4j
public class ChargeService {

    @Autowired
    private ParkPlaceMapper parkPlaceMapper;

    @Autowired
    private ParkZoneMapper parkZoneMapper;

    @Autowired
    private AlarmMapper alarmMapper;

    @Autowired
    private AccessRecordTodayMapper accessRecordTodayMapper;

    @Autowired
    private ReserveOrderMapper reserveOrderMapper;

    @Autowired
    private TodayOrderMapper todayOrderMapper;

    @Autowired
    private ChangeChargeMapper changeChargeMapper;

    @Autowired
    private PushService pushService;

//    @Autowired
//    private NotifyService notifyService;


    private boolean ifInList(String plateListStr, String carPlate) {
        String[] plateList;
        boolean intemplist = false;
        if (null != plateListStr) {
            plateList = plateListStr.split("\\|");
            for (String tempPlate : plateList) {
                if (carPlate.equalsIgnoreCase(tempPlate)) {
                    intemplist = true;
                }
            }
            if (intemplist) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 十五分钟不落位，则自动释放车位给预约
     */
    @Scheduled(cron = "0 */15 * * * ?")
    public void realseParkPlace() {
        log.info("自动释放分配未停放车位");
        List<ParkPlace> list = parkPlaceMapper.getParkPlaceBlankAndInOrder();
        for (ParkPlace parkPlace:list){
            parkPlace.setIfOrder(0);
            //看要不要摘除预约
            parkPlaceMapper.updateById(parkPlace);
        }
    }

    /**
     * 定时针对异常记录，未落位车辆信息读取，发送云智平台，通知，并变更计费规则
     */

    @Scheduled(cron = "0 */5 * * * ?")
    public void notifyAndChangeCharge() {

        QueryWrapper<Alarm> wrapper = new QueryWrapper<>();
        wrapper.eq("if_send", 0);
        List<Alarm> alarms = alarmMapper.selectList(wrapper);
        for (Alarm alarm : alarms) {
            //第一种告警，暂时不处理
            if (alarm.getExceptionType() == 1) {
                if (ChangeCharge(alarm)) {
                    //标记已经处理
                    alarm.setIfSend(1);
                    alarmMapper.updateById(alarm);
                }
            }
            //十五分钟没有落位
            else if (alarm.getExceptionType() == 2) {
                if (ChangeCharge(alarm)) {
                    //标记已经处理
                    alarm.setIfSend(1);
                    alarmMapper.updateById(alarm);
                }
            }
        }
    }

    private boolean ChangeCharge(Alarm alarm) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            ChangeCharge changeCharge = new ChangeCharge();
            changeCharge.setCarPlate(alarm.getCarPlate());
            changeCharge.setChangeType(alarm.getExceptionType());
            changeCharge.setChangeInfo(alarm.getParkInfo());
            changeCharge.setChangeDate(new Date());
            changeCharge.setZoneNo(ReadYZNo.codeProfile.get(alarm.getParkZoneNo()).getZoneNo());
            changeChargeMapper.insert(changeCharge);
            //变更车辆计费规则
//            PunitoryParkVO punitoryParkVO = new PunitoryParkVO();
//            punitoryParkVO.setParkId(parkZoneNo);
//            punitoryParkVO.setCarPlate(alarm.getCarPlate());
//            punitoryParkVO.setDateTime(sdf.format(new Date()));
//            punitoryParkVO.setPunitoryGrade("1");
//            punitoryParkVO.setBerthNumber(alarm.getParkInfo());
//            punitoryParkVO.setPunitoryReason(alarm.getContent());
//            notifyService.postPunitoryParkNotify(punitoryParkVO);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 十五分钟不落位，则记录异常，五分钟检测一次
     * 临停车位出现了没有订单的车辆，记为异常
     */
    @Scheduled(cron = "0 */5 * * * ?")
    public void recordNotInCorrectPlace() {
        List<ParkPlace> parkPlaceList = parkPlaceMapper.getParkPlaceNotBlank();
        for(ParkPlace parkPlace:parkPlaceList){
            String curPlate = parkPlace.getCurrPlate();
            //不是车位白名单，也不是预约车辆，视为占位停放
            if(!ifInList(parkPlace.getTempList(),curPlate) && !ifInList(parkPlace.getIgnorList(),curPlate)){
                Alarm alarm = new Alarm();
                alarm.setExceptionType(1);
                alarm.setCarPlate(curPlate);
                alarm.setUserName(parkPlace.getUserName());
                alarm.setParkZoneNo(parkPlace.getZoneId());
                alarm.setParkInfo(ReadYZNo.codeProfile.get(alarm.getParkZoneNo()).getZoneName()  + parkPlace.getParkNo() +"车位被占用,占用车牌:" + curPlate);
                alarm.setContent(ReadYZNo.codeProfile.get(alarm.getParkZoneNo()).getZoneName() + "车位被占用,占用车牌:" + curPlate);
                alarmMapper.insert(alarm);
                parkPlace.setUpdateStatus(1);
                parkPlaceMapper.updateById(parkPlace);
            }
        }

        /**
         * 查找所有有效订单里面的车牌
         */
        QueryWrapper<TodayOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("ifchecked", 0);
        List<TodayOrder> todayOrderList = todayOrderMapper.selectList(wrapper);
        for (TodayOrder todayOrder : todayOrderList) {
            //判断是否进场，如果进场，但不在临停区域，则做十五分钟判断
            String carPlate = todayOrder.getCarPlate();
            //看车牌今天是否入场
            AccessRecord accessRecord = accessRecordTodayMapper.getLastestRecord(carPlate);
            if (accessRecord != null) {
                if (accessRecord.getEventType().equalsIgnoreCase("IN")) {
                    //今天已经入场，并且最新状态是在场
                    Date now = new Date();
                    long diff = now.getTime() - accessRecord.getEventTime().getTime();
                    long days = diff / (1000 * 60 * 60 * 24);
                    long hours = (diff - days * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
                    long minutes = (diff - days * (1000 * 60 * 60 * 24) - hours * (1000 * 60 * 60)) / (1000 * 60);
                    //进场十五分钟，并在场
                    if (minutes > 15 || hours > 0) {
                        if (!ifInParkZone(todayOrder.getCarPlate(), todayOrder.getParkZoneId())) {
                            Alarm alarm = new Alarm();
                            alarm.setTime(now);
                            alarm.setParkInfo("车主电话号码:" + todayOrder.getPhoneNumber());
                            alarm.setCarPlate(carPlate);
                            alarm.setParkZoneNo(ReadYZNo.yzcodeProfile.get(todayOrder.getParkZoneId()).getZoneId());
                            alarm.setExceptionType(2);
                            alarm.setContent(carPlate + "十五分钟未到达指定车位!");
                            alarmMapper.insert(alarm);
                            //订单状态更新，避免重复处理,该车牌所有订单都标记，因为处理的已经是最新状态,存在多个订单
                            UpdateWrapper<ReserveOrder> updateWrapper = new UpdateWrapper<>();
                            updateWrapper.eq("car_plate", carPlate).set("ifchecked", 1);
                            reserveOrderMapper.update(null, updateWrapper);
                        }
                    }
                }
            }
            //如果没有进场，则保留订单
            else {
                continue;
            }
        }

    }

    /**
     * 通过车牌号，查询是否有订单
     *
     * @param carPlate
     * @return
     */
    public Result<ReserveOrder> ifHaveOrder(String carPlate) {
        QueryWrapper<ReserveOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("car_plate", carPlate).eq("status", 0);
        List<ReserveOrder> list = reserveOrderMapper.selectList(wrapper);
        if (list.size() > 0) {
            return Result.OK("查询成功", list.get(0));
        } else {
            return Result.Error("没有找到订单");
        }
    }

    /**
     * 查看车牌号在不在临停区
     */

    public boolean ifInParkZone(String carPlate, String zoneId) {
        QueryWrapper<ParkZone> zoneQueryWrapper = new QueryWrapper<>();
        zoneQueryWrapper.eq("zone_no", zoneId);
        ParkZone parkZone = parkZoneMapper.selectOne(zoneQueryWrapper);

        QueryWrapper<ParkPlace> wrapper = new QueryWrapper<>();
        wrapper.eq("curr_plate", carPlate).eq("zone_id", parkZone.getZoneId());

        return parkPlaceMapper.selectCount(wrapper) > 0;
    }
}
